<script setup>

import md5 from 'js-md5'
import {ref, onMounted, watch, watchEffect} from 'vue';
import axios from "axios";
import {snackbar} from './store'
// 导入依赖
import VueOfficeDocx from "@vue-office/docx";
// 导入样式文件
import "@vue-office/docx/lib/index.css";

// 查询
const itemsPerPage = ref(100);
const pageNo = ref(1);
const headers = [
    {title: '序号', key: 'num', sortable: false},
    {title: '活动名称', key: 'activityName', sortable: false},
    {title: '防守企业', key: 'defendName', sortable: false},
    {title: '漏洞总数', key: 'errorCount', sortable: false},
    {title: '得分', key: 'sumScore', sortable: false},
    {title: '操作', key: 'actions', sortable: false}
];
const detailsHeaders = [
    {title: '序号', key: 'num', sortable: false},
    {title: '攻方企业', key: 'attackName', sortable: false},
    {title: '被攻击系统名称', key: 'system_name', sortable: false},
    {title: '被攻击系统类别', key: 'systemTypeName', sortable: false},
    {title: '隐患级别', key: 'errorLevelName', sortable: false},
    {title: '隐患类型', key: 'errorTypeName', sortable: false},
    {title: '网络层级', key: 'netWorkLevelName', sortable: false},
    {title: '数据类型', key: 'dataTypeName', sortable: false},
    {title: '数据量', key: 'data_count', sortable: false},
    {title: '隐患IP', key: 'error_ip', sortable: false},
    {title: '漏洞描述', key: 'remark', sortable: false},
    {title: '操作', key: 'actions', sortable: false}
];
const items = ref([]);
const detailsList = ref([]);
const detailsTotal = ref(0);
const loading = ref(true);
const totalItems = ref(0);
const search = ref('');
const activityList = ref([]);
const activityId = ref(null);
const defendList = ref([]);
const defendId = ref(null);
const updatePasswordType = ref(false);
const sum = ref(0);
const userInfo = ref(JSON.parse(localStorage.getItem("ZAYY_USER_INFO")));
watch(activityId, () => {
    search.value = activityId.value
    axios.post('/activityJoin/select', {
        pageNo: 1,
        pageSize: 10000,
        activityId: activityId.value
    }).then(res => {
        defendList.value = res.data.records;
    })
})
watch(defendId, () => {
    search.value = defendId.value
})

function loadItems() {
    loading.value = true;
    axios.post('/attackRecord/errorReport', {
        activityId: activityId.value,
        defendId: defendId.value
    }).then(res => {
        items.value = res.data;
        items.value.forEach(item => {
            if(item.errorCount) {
                sum.value += Number(item.errorCount)
            }
        })
        totalItems.value = res.data.length;
        loading.value = false;
    })
}

function loadItemsDetails() {
    loading.value = true;
    axios.post('/attackRecord/errorReportDetail', {
        activityId: beDetailsItem.value.activity_id,
        defendId: beDetailsItem.value.defend_id
    }).then(res => {
        detailsList.value = res.data;
        detailsTotal.value = res.data.length;
        loading.value = false;
    })
}

onMounted(() => {
    axios.post('/activity/select', {
        pageNo: 1,
        pageSize: 1000
    }).then(res => {
        activityList.value = res.data.records;
        activityId.value = userInfo.value.activityId
            axios.post('/activityJoin/select', {
                pageNo: 1,
                pageSize: 10000,
                activityId: activityId.value
            }).then(res => {
                defendList.value = res.data.records;
            })
    })
});

// 增改
const isShowDialog = ref(false)
const dialogEnum = {
    update: '详情',
    create: '新增'
}
const dialogType = ref(null)
const isShowDeleteDialog = ref(false)
const editedItem = ref({
    status: "1"
});

function resetEditedItem() {
    editedItem.value = {}
}

function clickNew() {
    dialogType.value = dialogEnum.create
    resetEditedItem()
    updatePasswordType.value = true
    isShowDialog.value = true
}

function close() {
    isShowDialog.value = false
    resetEditedItem()
    dialogType.value = null
}

const beDetailsItem = ref({})
function clickEdit(item) {
    isShowDialog.value = true
    beDetailsItem.value = item
    dialogType.value = dialogEnum.update
}

function save() {
    if (dialogType.value === dialogEnum.update) {
        let obj = JSON.parse(JSON.stringify(editedItem.value))
        if(updatePasswordType.value) {
            obj.password = md5(obj.password)
        }
        axios({
            method: 'POST',
            url: '/user/updateUser',
            data: obj
        }).then(() => {
            snackbar.info('编辑成功')
            close()
            loadItems({page: pageNo.value, itemsPerPage: itemsPerPage.value})
        })
    } else if (dialogType.value === dialogEnum.create) {
        let obj = JSON.parse(JSON.stringify(editedItem.value))
        obj.password = md5(obj.password)
        axios({
            method: 'POST',
            url: '/user/saveUser',
            data: obj
        }).then(() => {
            snackbar.info('创建成功')
            close()
            loadItems({page: pageNo.value, itemsPerPage: itemsPerPage.value})
        }, err => {
            snackbar.info(err.response.data.message)
        })
    }
}

// 删
const beDeleteItem = ref({})

function clickDelete(item) {
    isShowDeleteDialog.value = true
    beDeleteItem.value = item
}

function clickDeleteConfirm() {
    axios.post('/user/delUser?userId=3', obj).then(() => {
        snackbar.info("操作成功")
        loadItems({page: pageNo.value, itemsPerPage: itemsPerPage.value})
        clickCloseDelete()
    })
}

function clickCloseDelete() {
    isShowDeleteDialog.value = false
    beDeleteItem.value = {}
}

function uploadFile() {
    if(editedItem.value.photoUrlUpload.length) {
        var formData = new FormData();
        formData.append('file', editedItem.value.photoUrlUpload[0])
        axios({
            method: "POST",
            url: "/basBlack/uploadImage",
            data: formData,
            headers: {
                'Content-Type': "multipart/form-data"
            }
        }).then(res => {
            if(res.data.code == 200) {
                snackbar.info("上传成功")
                editedItem.value.avatar = res.data.data
            }
        })
    }
}

function clickDownload() {
    if(!activityId.value) {
        snackbar.info("请选择活动")
        return
    }
    let obj = {
        activityId: activityId.value
    }
    axios({
        method: "POST",
        url: "/attackRecord/downloadReport",
        responseType: 'blob',
        data: obj
    }).then(res => {
        console.log(res.data)
    }, err => {
        snackbar.info("开始下载")
        console.log(err)
        let blob = new Blob([err.data], {type: "application/vnd.ms-excel"});
        let fileName = `漏洞报表.xlsx`
        if ("download" in document.createElement("a")) {
            // 支持a标签download的浏览器
            const link = document.createElement("a"); // 创建a标签
            link.download = fileName; // a标签添加属性
            link.style.display = "none";
            link.href = URL.createObjectURL(blob);
            document.body.appendChild(link);
            link.click(); // 执行下载
            URL.revokeObjectURL(link.href); // 释放url
            document.body.removeChild(link); // 释放标签
        } else {
            // 其他浏览器
            navigator.msSaveBlob(blob, fileName);
        }
    })
}

const baseUrl = ref("http://101.68.222.195:8099/netDefense/");
const htmlShow = ref(false);
const docxSrc = ref("");
function clickDownloadWord(val) {
    let url = `${baseUrl.value}whiteApi/${val.activity_id}&${val.file}`
    docxSrc.value = url
    htmlShow.value = true
}

</script>

<template>
    <v-toolbar density="compact">
        <v-toolbar-title>
            漏洞报表
            <font style="font-size: 17px;">(漏洞总数：{{ sum }})</font>
        </v-toolbar-title>
        <v-autocomplete :items="activityList" item-title="name" item-value="id" v-model="activityId" :clearable="userInfo.userType == 1" :readonly="userInfo.userType != 1" hide-details label="查询活动"></v-autocomplete>
        <v-autocomplete :items="defendList" item-title="companyName" item-value="defendId" v-model="defendId" :clearable="true" hide-details label="查询企业"></v-autocomplete>
        <v-dialog v-model="isShowDialog" max-width="1600px">
            <!-- <template v-slot:activator="{ props }">
                <v-btn icon="mdi-plus" v-on:click="clickNew" v-bind="props"></v-btn>
            </template> -->
            <v-card>
                <v-card-title>{{ dialogType }}</v-card-title>
                <v-card-text>
                    <v-data-table-server :items-per-page="itemsPerPage" :headers="detailsHeaders" :items-length="detailsTotal"
                    :items="detailsList"
                    :loading="loading"
                    class="elevation-1"
                    items-per-page-text="每页数量"
                    @update:options="loadItemsDetails">
                        <template v-slot:item.num="{ index }">
                            <span>{{ index + 1 }}</span>
                        </template>
                        <template v-slot:item.actions="{ item }">
                            <v-tooltip text="查看漏洞" location="bottom">
                                <template v-slot:activator="{ props }">
                                    <v-btn icon="mdi-book-search" 
                                    variant="text" v-on:click="clickDownloadWord(item)" v-bind="props"></v-btn>
                                </template>
                            </v-tooltip>
                        </template>
                    </v-data-table-server>

                    <v-dialog v-model="htmlShow" max-width="1000px" fullScreen>
                        <v-card>
                            <v-toolbar density="compact">
                                <v-btn icon="mdi-close" @click="htmlShow = false"></v-btn>
                                <v-toolbar-title>漏洞信息</v-toolbar-title>
                            </v-toolbar>
                            <VueOfficeDocx :src="docxSrc" />
                        </v-card>
                    </v-dialog>
                </v-card-text>
                <v-card-actions>
                    <v-btn color="primary" variant="text" @click="close">关闭</v-btn>
                </v-card-actions>
            </v-card>
        </v-dialog>
        <v-btn icon="mdi-download" v-on:click="clickDownload" v-bind="props"></v-btn>
        <v-dialog v-model="isShowDeleteDialog" max-width="500px">
            <v-card>
                <v-card-title class="text-h5">确定删除该用户?</v-card-title>
                <v-card-actions>
                    <v-spacer></v-spacer>
                    <v-btn color="blue-darken-1" variant="text" @click="clickCloseDelete">取消</v-btn>
                    <v-btn color="blue-darken-1" variant="text" @click="clickDeleteConfirm">确定</v-btn>
                    <v-spacer></v-spacer>
                </v-card-actions>
            </v-card>
        </v-dialog>
    </v-toolbar>
  <!--  分页文本待更换   items-per-page-text="每页数量"-->
    <v-data-table-server :search="search" :items-per-page="itemsPerPage" :headers="headers" :items-length="totalItems"
    :items="items"
    :loading="loading"
    class="elevation-1"
    items-per-page-text="每页数量"
    @update:options="loadItems">
        <template v-slot:item.num="{ index }">
            <span>{{ index + 1 }}</span>
        </template>
        <template v-slot:item.actions="{ item }">
            <v-btn icon="mdi-search-web" variant="text" @click="clickEdit(item)"></v-btn>
            <!-- <v-btn icon="mdi-delete" variant="text" @click="clickDelete(item)"></v-btn> -->
        </template>
    </v-data-table-server>
</template>

<style scoped>
:deep(.v-data-table__tr:nth-child(odd) .v-data-table__td) {
    background-color: rgba(240, 240, 240, 0.40);
}
:deep(.v-data-table__tr .v-data-table__td) {
    border: none !important;
}
:deep(.v-data-table__thead .v-data-table__td) {
    border: none !important;
}
</style>
